from flask import (Blueprint, request, abort)
from db import DBSession, User, Role, Author
from utils import normalizeRes
import datetime
import hashlib


bp = Blueprint('user', __name__, url_prefix='/api/system/user')


# 登陆
@bp.route('/login', methods=['POST'])
def login():
    session = DBSession()
    post_data = request.json
    if not request.json.get('username'):
        abort(400)
    if not request.json.get('password'):
        abort(400)
    try:
        h = hashlib.sha256()
        h.update(request.json.get('password').encode(encoding='utf-8'))
        user = session.query(User).filter_by(user_name=post_data.get('username')).scalar()
        if h.hexdigest() == user.password:
            # 更新最后登录时间
            user.last_login_time = datetime.datetime.now()
            # 更新登录次数
            user.login_count = user.login_count + 1 if user.login_count else 1
            # 更新访问IP
            user.last_login_ip = request.remote_addr
            # 获取登录用户的角色
            roles = list(map(lambda role: {'roleId': role.role_id, 'roleName': role.name}, user.roles))
            # 获取该用户的所有权限菜单
            menus = session.query(Author).all()
            new_menus = []
            for menu in menus:
                res = list(set(map(lambda a: a.get('roleId'), roles)) & set(map(lambda b: b.role_id, menu.roles)))
                if res:
                    new_menus.append({
                        'id': menu.id,
                        'name': menu.name,
                        'isMenu': menu.is_menu,
                        'url': menu.url,
                        'code': menu.code,
                        'isEffective': menu.is_effective,
                        'actions': menu.operate.split(','),
                        'editor': menu.editor,
                        'editTime': menu.edit_time
                    })

            session.commit()
            return normalizeRes({
                'roles': roles,
                'token': 'admin',
                'name': user.user_name,
                'menus': new_menus
            })
        else:
            abort(400)
            return normalizeRes(None, success=False, message='密码错误!')
    except Exception as e:
        print(e)
        return normalizeRes(None, success=False, message='密码错误!')
    finally:
        session.close()


# 获取用户列表
@bp.route('/list', methods=['GET'])
def get_users():
    session = DBSession()
    params = request.args
    users = session.query(User)
    # 判断是否生效中
    if len(params.get('disable')) > 0:
        is_disable = False
        if params.get('disable') == 'true':
            is_disable = True
        users = users.filter(User.is_disable == is_disable)
    # 名字模糊查询
    if params.get('userName'):
        users = users.filter(User.user_name.like('%' + params.get('userName') + '%'))
    total = users.count()
    users = users.limit(int(params.get('pageSize', 10)))\
        .offset((int(params.get('current', 1)) - 1) * int(params.get('pageSize', 10))).all()
    user_list = []
    for user in users:
        roles = list(map(lambda role: {'roleId': role.role_id, 'roleName': role.name}, user.roles))
        user_list.append({
            'userId': user.user_id,
            'userName': user.user_name,
            'realName': user.real_name,
            'roles': roles,
            'registerTime': user.register_time,
            'lastLoginTime': user.last_login_time,
            'lastLoginIP': user.last_login_ip,
            'loginCount': user.login_count,
            'isDisable': user.is_disable
        })
    session.close()
    return normalizeRes({
        'list': user_list,
        'total': total
    })


# 创建用户
@bp.route('/create', methods=['POST'])
def create_user():
    try:
        session = DBSession()
        if not request.json['userName']:
            abort(400)
        if not request.json['realName']:
            abort(400)
        h = hashlib.sha256()
        h.update('123456'.encode(encoding='utf-8'))
        new_user = User(
            user_name=request.json['userName'],
            password=h.hexdigest(),
            real_name=request.json['realName'],
            home_phone=request.json.get('homePhone'),
            mobile=request.json.get('mobile'),
            email=request.json.get('email'),
            gender=request.json.get('gender', 1),
            is_disable=request.json.get('isDisable', False),
            register_time=datetime.datetime.now()
        )
        new_user.roles = session.query(Role).filter(Role.role_id.in_(request.json.get('roleIds'))).all()
        session.add(new_user)
        session.commit()
        session.close()
        return normalizeRes({
            'new_user': request.json
        })
    except Exception as e:
        print("创建用户错误：" + e)
    finally:
        session.close()


# 获取用户详情
@bp.route('/detail/<int:userId>', methods=['GET'])
def get_user_detail(userId):
    session = DBSession()
    user = session.query(User).filter_by(user_id=userId).one()
    roles = list(map(lambda role: role.role_id, user.roles))
    session.close()
    return normalizeRes({
        'userId': user.user_id,
        'userName': user.user_name,
        'realName': user.real_name,
        'homePhone': user.home_phone,
        'email': user.email,
        'mobile': user.mobile,
        'gender': user.gender,
        'isDisable': user.is_disable,
        'roles': roles
    })


# 修改用户
@bp.route('/detail/<int:userId>', methods=['PUT'])
def modify_user_detail(userId):
    try:
        updateuser = request.json
        session = DBSession()
        user = session.query(User).filter_by(user_id=userId).scalar()
        user.user_name = updateuser.get('userName', user.user_name)
        user.real_name = updateuser.get('realName', user.real_name)
        user.home_phone = updateuser.get('homePhone', user.home_phone)
        user.mobile = updateuser.get('mobile', user.mobile)
        user.email = updateuser.get('email', user.email)
        user.gender = updateuser.get('gender', user.gender)
        user.is_disable = updateuser.get('isDisable', user.is_disable)
        user.roles = session.query(Role).filter(Role.role_id.in_(updateuser.get('roles', []))).all()
        result = normalizeRes({
            'userId': user.user_id,
            'userName': user.user_name,
            'realName': user.real_name,
            'homePhone': user.home_phone,
            'mobile': user.mobile,
            'email': user.email,
            'gender': user.gender,
            'isDisable': user.is_disable,
            'roles': list(map(lambda role: role.role_id, user.roles))
        })
        session.commit()
        return result
    except Exception as e:
        print(e)
    finally:
        session.close()


# 启用/禁用用户
@bp.route('/enable/<int:userId>', methods=['PUT'])
def change_user_state(userId):
    try:
        session = DBSession()
        if not request.json['disable']:
            abort(400)
        user = session.query(User).filter(User.user_id == userId).one()
        user.is_disable = request.json.get('disable')
        session.commit()
        return normalizeRes({
           'res': True
        })
    except Exception as e:
        print('更改用户信息出错:' + e)
    finally:
        session.close()

